//
//  ActiveAIChatExt.swift
//  imprint
//
//  Created by 小柠檬🍋 on 2025/3/11.
//

import Foundation
import SwiftUI

//检查是否有日记需要回复
class ActiveAICommentExt  : BaseViewModel {
    static let instance = ActiveAICommentExt()

    private var mapDelay: [String:Bool] = [:]
    private let modeType = IAiModelType.diaryReply.rawValue
    private let mapQueue = DispatchQueue(label: "mapDelayQueue")
    
    private func getKey(_ id : String?, _ aiRoleId : String?) -> String {
        return "\(id ?? "")_\(aiRoleId ?? "")"
    }
    
    
    func getMapValue(_ key: String) -> Bool {
        return mapQueue.sync {
            self.mapDelay[key] ?? false
        }
    }
    
    func putMapValue(_ key: String,_ bool: Bool) {
        return mapQueue.sync {
            self.mapDelay[key] = bool
        }
    }
    
    func removeMapValue(_ key: String) {
        return mapQueue.sync {
            self.mapDelay.removeValue(forKey: key)
        }
    }
    func checkComment() {
        request(isLoading: false,timeout: 60 * 60){
            let list = try await BackupsManager.shared.getDelegateDiary()?.queryDiaryUpdateAll(userId: userManager.getUserId(), pageNo: 0, pageSize: 20) ?? []
            for diary in list {
                //try await DiaryExt.dealPicture([diary], true)
                showLog("检查日记信息" + (diary.content ?? ""))
                var listRole : [String] = []
                if diary.roleType == IRoleType.BOT.rawValue {
                    listRole.append(diary.roleId ?? "")
                } else {
                    listRole = diary.aiRule?.listAiRole?.map{ $0.roleId ?? "" } ?? []
                    //如果多人回复没有，则查找单人回复
                    if listRole.isEmpty {
                        listRole.append(diary.aiRule?.aiRoleId ?? "")
                    }
                }
                for roleId in listRole {
                    let lastDiaryCommentBean = try await BackupsManager.shared.getDelegateDiary()?.queryDiaryLast(diaryId: diary.objectId ?? "", aiRoleId: roleId)
                    //如果最后一条消息是用户的，则需要主动发起回复
                    if (lastDiaryCommentBean?.role?.isUser() == true) {
                        var listComment : [DiaryCommentBean] = []
                        if diary.isMultiple() {
                            //多人回复才需要传递roleId，因为旧版本没有
                            let listData = try await BackupsManager.shared.getDelegateDiary()?.queryDiaryComment(diaryId: diary.objectId ?? "", aiRoleId: roleId, pageNo: 0, pageSize: 100) ?? []
                            listComment.append(contentsOf: listData)
                        } else {
                            let listData = try await BackupsManager.shared.getDelegateDiary()?.queryDiaryComment(diaryId: diary.objectId ?? "", pageNo: 0, pageSize: 100) ?? []
                            listComment.append(contentsOf: listData)
                        }
                        //添加ai的日记回复,日记回复添加第一个
                        let aiRole = try await BackupsManager.shared.getDelegateConfig()?.getAiRole(roleId: roleId)
                        let aiReply = diary.getAiReply(aiRoleId: roleId)
                        if aiReply.isEmpty == false {
                            let bean = DiaryCommentBean()
                            bean.diaryId = diary.objectId
                            bean.role = RoleBean.get(aiRole!)
                            bean.content = aiReply
                            bean.time = diary.time
                            listComment.insert(bean, at: 0)
                        }
                        self.doAiReply(diary,listComment, aiRole!)
                        
                    }
                }
            }
            return list
        } suc: { list in
            
        } fail: { _ in
            
        }
    }
    
    func doAiReply(_ diaryBean: DiaryBean,
                   _ list: [DiaryCommentBean],
                   _ aiRoleBean: AiRoleBean,
                   _ force: Bool = false,
                   _ backup: Bool = false
    ) {
        let diaryIdFinal = diaryBean.objectId
        let aiRoleIdFinal = aiRoleBean.objectId
        var errorApi = ""
        request(isLoading: false,timeout: 60 * 60){
            //            try check(!isExamine()) {
            //                "审核版本，不开启功能"
            //            }
            try check(AppStorageManager.shared.toggleAi) {
                "AI 功能已关闭"
            }
            try check(AppStorageManager.shared.toggleAiComment) {
                "AI 评论功能已关闭"
            }
            try check(AiChatExt.isAiEnabled() || AiCustomUtils.shared.isCustomAi(type: self.modeType)) {
                "AI 功能已用尽,请前往活动领取次数"
            }
            try check(!list.isEmpty) {
                "数据为空，不继续评论"
            }
            let lastBean = list.last
            try check(!(lastBean?.role?.isBot() ?? false)) {
                "最后一条是AI，不继续评论"
            }
            let exit  = self.getMapValue(self.getKey(diaryIdFinal, aiRoleIdFinal))
            try check(exit == false) {
                "该日记角色已进入延迟阶段"
            }
            self.putMapValue(self.getKey(diaryIdFinal, aiRoleIdFinal),true)
            
            let botRoleBean = RoleBean.get(aiRoleBean)
            let isEnd = list.count > configManager.getConfig().aiChat.diaryCommentCount ?? 0 && Bool.random()
            //批量更改名字
            for it in list {
                //由于存在名字、头像更改问题，所以评论里面的名字需要批量修改
                it.role = try await DiaryExt.getRole(it)
            }
            let aiModel: Int  = configManager.getConfig().aiChat.getAiModel(aiMode: IAiModelType.comment)
            var replyStr : String = ""
            if backup {
                //启动备用方案
                try await retry(maxRetries: 3, retryDelayMillis: 500) {
                    let aiModeBean = configManager.getConfig().getAiChatMode2(key: self.modeType)
                    errorApi = "\(aiModeBean.host ?? ""),\(aiModeBean.model ?? "")"
                    let bean = AICommentRequestBean(model : aiModeBean.model, diary: diaryBean, list: list, botRoleBean: botRoleBean, isEnd: isEnd)
                    showLog("请求AI：\(String(describing: toJson(bean)))")
                    let result = try await AiNetManager.shared.requestAI(host: aiModeBean.host, token: aiModeBean.token, jsonObject: toJson(bean), modeType: AIChatResultBean.self)
                    replyStr = result.getReplyStr()
                    showLog(replyStr)
                }
            } else if AiCustomUtils.shared.isCustomAi(type: self.modeType) {
                //自定义
                try await retry(maxRetries: 3, retryDelayMillis: 500) {
                    let host = AiCustomUtils.shared.getCustomHost(type: self.modeType)
                    let token = AiCustomUtils.shared.getCustomToken(type: self.modeType)
                    let model = AiCustomUtils.shared.getCustomModel(type: self.modeType)
                    errorApi = "\(host),\(model)"
                    let bean = AICommentRequestBean(model : model, diary: diaryBean, list: list, botRoleBean: botRoleBean, isEnd: isEnd)
                    showLog("请求AI：\(String(describing: toJson(bean)))")
                    let result = try await AiNetManager.shared.requestAI(host: host, token: token, jsonObject: toJson(bean), modeType: AIChatResultBean.self)
                    replyStr = result.getReplyStr()
                    showLog(replyStr)
                }
            } else {
                switch aiModel {
                case 1,2:
                    //配置模型
                    try await retry(maxRetries: 1, retryDelayMillis: 500) {
                        let aiModeBean = configManager.getConfig().getAiChatMode(key: self.modeType)
                        errorApi = "\(aiModeBean.host ?? ""),\(aiModeBean.model ?? "")"
                        let bean = AICommentRequestBean(model : aiModeBean.model, diary: diaryBean, list: list, botRoleBean: botRoleBean, isEnd: isEnd)
                        showLog("请求AI：\(String(describing: toJson(bean)))")
                        let result = try await AiNetManager.shared.requestAI(host: aiModeBean.host, token: aiModeBean.token, jsonObject: toJson(bean), modeType: AIChatResultBean.self)
                        replyStr = result.getReplyStr()
                        showLog(replyStr)
                    }
                default:
                    //minmax 模型
                    try await retry(maxRetries: 3, retryDelayMillis: 500) {
                        let bean = AICommentMinmaxBean(diary: diaryBean, list: list, botRoleBean: botRoleBean)
                        showLog("请求AI：：\(String(describing: toJson(bean)))")
                        let result = try await AiNetManager.shared.requestAIMinMax(jsonObject: toJson(bean), modeType: AIChatResultMinmaxBean.self)
                        replyStr = result.getReplyStr(true)
                    }
                    break
                    
                }
            }
            try check(!isAiReplyProhibit(replyStr), "AI含有违禁词")
            diaryBean.commentCount = list.count + 1
            if (isEnd) {
                diaryBean.closeComment = true
                
            }
            //开始保存日记
            try await retry(maxRetries: 10, retryDelayMillis: 500) {
                try await BackupsManager.shared.getDelegateDiary()?.saveDiary(bean: diaryBean)
            }
            //开始保存评论
            let diaryCommentBean = DiaryCommentBean()
            try await retry(maxRetries: 10, retryDelayMillis: 500) {
                diaryCommentBean.diaryId = diaryBean.objectId
                diaryCommentBean.role = botRoleBean
                diaryCommentBean.content = replyStr
                diaryCommentBean.time = getMillisecond(Date().timeIntervalSince1970)
                diaryCommentBean.roleId = botRoleBean.roleId
                _ = try await BackupsManager.shared.getDelegateDiary()?.addDiaryComment(bean: diaryCommentBean)
            }
            return diaryCommentBean
        } suc: { diaryCommentBean in
            if !AiCustomUtils.shared.isCustomAi(type: self.modeType) {
                AiChatExt.deductAiChatCountCommon()
            }
            self.removeMapValue(self.getKey(diaryIdFinal, aiRoleIdFinal))
            //发送通知
            NotificationCenter.default.post(name: .addComment, object: diaryCommentBean)
            NotificationCenter.default.post(name: .updateComment, object: diaryCommentBean)
            if diaryBean .closeComment == true {
                NotificationCenter.default.post(name: .updateDiary, object: diaryBean)
            }
            //系统通知
            if commonManager.isBackground {
                showLocalNotification(aiRoleBean.name ?? "", "给你评论了一条消息")
            }
            
        } fail: { it in
            self.removeMapValue(self.getKey(diaryIdFinal, aiRoleIdFinal))
            if ERROR.NET_ERRPR.rawValue == it.code {
                AiChatExt.reportError(
                    type: self.modeType,
                    typeName: "评论",
                    message: it.realMessage,
                    errorApi: errorApi)
                
                if let error = configManager.getConfig().getAiError(content: it.realMessage) {
                    showToast(error)
                }
            } else {
                //非自定义使用备用方案
                if !backup && !AiCustomUtils.shared.isCustomAi(type: self.modeType) {
                    showLog("评论使用备用方案")
                    self.doAiReply(diaryBean,list,aiRoleBean,force,true)
                }
            }
        }
        
    }
    
}

